using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.InteropServices;
using IniParser;
using Microsoft.Win32;
using Mod工具.Util;
using SevenZip;

namespace Mod工具
{
    public partial class Form1 : Form
    {

        private const int SwMinimize = 6;

        //全局string变量游戏路径
        private static string? _gamePath; //游戏路径
        private static string? _modPath; //mod路径
        private static string? _patchPath; //补丁路径
        private static bool _firstRun = true;
        private static List<string> _modList = new();
        private static string _suffix = ".7z";

        public Form1()
        {
            InitializeComponent();
        }

        [DllImport("user32.dll")]
        private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);

        private void Form1_Load(object sender, EventArgs e)
        {
            if (_firstRun)
            {
                _firstRun = false;
                if (File.Exists(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AppConfig.ini")))
                {
                    Console.WriteLine("AppConfig.ini文件存在，读取配置文件");
                    var parser = new FileIniDataParser();
                    var data =
                        parser.ReadFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "AppConfig.ini"));
                    _suffix = data["AppConfig"]["Suffix"];
                }

                Registry.LocalMachine.CreateSubKey("SOFTWARE\\BH6MOD\\Mod管家\\AppData\\modList");
                Directory.CreateDirectory("./mods");
                DatabaseHelper.SetConnectionString("101.132.40.214", "spirithun", "spirithun", "euU9EgTWW8uOMt8m",
                    3306);
                DatabaseHelper.ConnectToDatabase();
                MessageBox.Show("欢迎使用本软件！软件与计算机绑定，移动复制将无法使用本软件！", "Mod管家", MessageBoxButtons.OK,
                    MessageBoxIcon.Information);
            }

            if (SafeAppTools.IsGetGamePath())
            {
                _gamePath = GetGamePath.Text = SafeAppTools.GamePath;
                _patchPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC";
                _modPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC\\arc\\DX9";
                GetGamePath.Enabled = false;
            }

            // 确保已选择了列表中的项
            if (ModList.SelectedIndex == -1)
            {
                UnLockMod.Enabled = InstallMod.Enabled = false;
            }

            if (SafeAppTools.IsRegistered())
            {
                Text = "Mod管家 - 已激活";
                return;
            }

            Text = "Mod管家 - 未激活";
            MessageBox.Show("软件未激活，请先激活软件！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
            //载入register窗口
            var register = new Register();
            register.ShowDialog();
            //销毁主窗口
            Close();


        }

        private void GetGamePath_Click(object sender, EventArgs e)
        {
            // 尝试获取正在运行的“bh6”和“BH6”进程。
            var processes = Process.GetProcessesByName("bh6");
            var processesCaps = Process.GetProcessesByName("BH6");

            // 检查是否有对应的进程正在运行，如果没有则显示错误信息。
            if (processes.Length == 0 && processesCaps.Length == 0)
            {
                MessageBox.Show("未检测到游戏，请先运行生化危机6！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
            }
            else
            {
                try
                {
                    string gamePath = (processes.Length != 0 ? processes[0].MainModule : processesCaps[0].MainModule)
                                      ?.FileName
                                      ?? throw new InvalidOperationException("无法获取游戏路径。");
                    // 设置游戏路径到文本框和私有变量中。
                    _gamePath = GetGamePath.Text = gamePath;

                    // 计算MOD和补丁的路径。
                    _modPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC";
                    _patchPath = _gamePath.Replace("\\bh6.exe", "\\") + "nativePC\\arc\\DX9";

                    // 终止检测到的游戏进程。
                    processes[0].Kill();
                    processesCaps[0].Kill();

                    // 显示成功获取游戏路径的消息。
                    MessageBox.Show("游戏路径获取成功！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);

                    // 禁用获取游戏路径按钮，防止重复获取。
                    GetGamePath.Enabled = false;

                    // 将游戏路径保存到注册表中。
                    var key = Registry.LocalMachine.CreateSubKey(@"SOFTWARE\BH6MOD\Mod管家\AppData");
                    key.SetValue("gamePath", gamePath);
                    key.Close();
                }
                catch (InvalidOperationException ex)
                {
                    // 处理获取游戏路径失败的异常。
                    MessageBox.Show(ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
                catch (Win32Exception ex)
                {
                    // 处理Windows API调用失败的异常。
                    MessageBox.Show("获取游戏路径失败：" + ex.Message, "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }
        }

        //ModList选中事件
        private void ModList_SelectedIndexChanged(object sender, EventArgs e)
        {
            Console.WriteLine($"已选择：{ModList.Text}");

            // 注册表项路径
            const string registryPath = @"SOFTWARE\BH6MOD\Mod管家\AppData\modList";
            // 获取选中的列表项文本
            string selectedItem = ModList.Text;

            // 初始化按钮状态
            bool isUnLockModEnabled = true;
            bool isInstallModEnabled = false;

            try
            {
                // 尝试直接打开选中项对应的注册表子项（只读模式）
                using var subKey = Registry.LocalMachine.OpenSubKey($"{registryPath}\\{selectedItem}", false);
                if (subKey != null)
                {
                    // 如果选中的项对应的注册表子项存在
                    // 禁用UnLockMod按钮，启用InstallMod按钮
                    isUnLockModEnabled = false;
                    isInstallModEnabled = true;
                }
                else if (_modList.Contains(selectedItem))
                {
                    isUnLockModEnabled = true;
                    isInstallModEnabled = false;
                }
                else
                {
                    isUnLockModEnabled = true;
                }
            }
            catch (Exception ex)
            {
                // 异常处理：记录日志或显示错误消息
                Console.WriteLine($"访问注册表时发生错误：{ex.Message}");
            }

            // 更新按钮状态
            UnLockMod.Enabled = isUnLockModEnabled;
            InstallMod.Enabled = isInstallModEnabled;
        }


        private void UnLockMod_Click(object sender, EventArgs e)
        {
            if (ModList.SelectedIndex == -1)
            {
                MessageBox.Show("请先选择要解锁的mod！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (UnlockKey.Text == "")
            {
                MessageBox.Show("请输入解锁码！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            int status = DatabaseHelper.GetModUnKeyStatus(UnlockKey.Text, ModList.Text);
            switch (status)
            {
                case -1:
                    MessageBox.Show("解锁码无效！请检查您的解锁码！或者联系作者！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case -2:
                    MessageBox.Show("解锁码已被使用！请重新获取解锁码！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                    break;
                case 1:
                    //弹窗提示，解锁成功
                    MessageBox.Show("解锁成功！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    break;
            }
        }

        private void Scan_Click(object sender, EventArgs e)
        {
            ModList.Items.Clear();
            MessageBox.Show("请将mod文件放到 mods文件夹下软件即可扫描！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
            string[] files = Directory.GetFiles("./mods", $"*{_suffix}"); //此处可定制后缀，默认为7z
            foreach (string file in files)
            {
                string fileName = Path.GetFileNameWithoutExtension(file);
                ModList.Items.Add(fileName);
            }

            MessageBox.Show("扫描完成！共找到" + files.Length + "个mod文件！", "Mod管家", MessageBoxButtons.OK,
                MessageBoxIcon.Information);
        }

        private void InstallMod_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(_gamePath))
            {
                MessageBox.Show("请先获取游戏路径！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (ModList.SelectedIndex == -1)
            {
                MessageBox.Show("请先选择要安装的mod！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            if (!SafeAppTools.ModExist(ModList.Text)) return;
            var modInfo = SafeAppTools.GetModData(SafeAppTools.ModKey);

            // 直接在一个if语句中检查ModName不为null并且ModUnZipPassword也不为null
            if (modInfo is not { ModName: not null, ModUnZipPassword: not null }) return;
            UnPackMod(modInfo.ModName, modInfo.ModUnZipPassword);
            _modList.Add(modInfo.ModName);
            InstallMod.Enabled = false;
        }

        private static void UnPackMod(string modName, string modUnZipPassword)
        {
            // 获取当前应用程序域的基础目录
            string basePath = AppDomain.CurrentDomain.BaseDirectory;
            // 拼接7z.dll文件的路径
            string libPath = Path.Combine(basePath, Environment.Is64BitOperatingSystem ? "x64" : "x86", "7z.dll");
            // 设置7-Zip库的路径
            SevenZipBase.SetLibraryPath(libPath);
            try
            {
                // 创建SevenZipExtractor对象，用于解压模组文件
                using var extractor = new SevenZipExtractor(Path.Combine(basePath, "mods", $"{modName}{_suffix}"),
                    modUnZipPassword);
                // 解压文件并备份
                ExtractAndBackupFiles(extractor);
                // 显示成功安装模组的消息框
                MessageBox.Show("Mod安装成功！", "Mod管家", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }
            catch (Exception e)
            {
                // 打印异常信息到控制台，并重新抛出异常
                Console.WriteLine(e);
                throw;
            }
        }

        private static void ExtractAndBackupFiles(SevenZipExtractor extractor)
        {
            // 遍历压缩文件中的所有文件信息
            foreach (var archiveFileInfo in extractor.ArchiveFileData)
            {
                // 如果_modPath为空，则跳过当前循环
                if (_patchPath == null) continue;

                // 构造文件的完整路径
                string fullPath = Path.Combine(_patchPath, archiveFileInfo.FileName);

                // 获取文件所在的目录路径
                string? directoryPath = Path.GetDirectoryName(fullPath);

                // 判断目录名是否为"SpiritHun6"
                string? directoryName = directoryPath != null ? Path.GetFileName(directoryPath) : null;
                if (directoryName == "SpiritHun6") continue; // 如果是，跳过当前循环

                // 如果文件已存在
                if (File.Exists(fullPath))
                {
                    // 构造备份文件的路径
                    string backupPath = $"{fullPath}.bak";

                    // 如果备份文件已存在，则删除它
                    if (File.Exists(backupPath))
                    {
                        File.Delete(backupPath);
                    }

                    // 将现有文件移动到备份路径
                    File.Move(fullPath, backupPath);
                }

                // 如果目录不存在且directoryPath不为null，则创建该目录
                if (directoryPath != null && !Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }
            }

            // 在指定的路径下提取压缩文件的所有内容
            extractor.ExtractArchive(_patchPath);
        }

        private void StartGame_Click(object sender, EventArgs e)
        {
            IntPtr mainWindowHandle = Process.GetCurrentProcess().MainWindowHandle;
            Process.Start(GetGamePath.Text);
            ShowWindow(mainWindowHandle, SwMinimize);
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (MessageBox.Show("是否退出管理工具？退出后所有MOD将还原！", "Mod管家", MessageBoxButtons.YesNo, MessageBoxIcon.Warning) !=
                DialogResult.Yes)
                return;
            // 检查并终止游戏进程
            foreach (var process in Process.GetProcesses())
            {
                if (!process.ProcessName.ToLower().Equals("bh6") &&
                    !process.ProcessName.ToLower().Equals("BH6")) continue;
                try
                {
                    process.Kill(); // 终止进程
                }
                catch (Exception killException)
                {
                    Console.WriteLine($"尝试终止进程 {process.ProcessName} 时出现异常: {killException.Message}");
                    // 可选择是否通知用户进程终止失败
                }
            }

            // 如果_modPath不为空，执行下面的清理和备份还原操作
            if (_modPath != null)
            {
                // 尝试删除数据目录下的"SpiritHun6"目录
                try
                {
                    Directory.Delete(_patchPath + "\\SpiritHun6", true);
                    Console.WriteLine($"正在处理目录 {_patchPath}\\SpiritHun6");
                }
                catch (Exception exception)
                {
                    // 打印删除目录时可能出现的异常信息
                    Console.WriteLine($"处理目录 {_patchPath}\\SpiritHun6 时出现异常: {exception.Message}");
                }

                // 遍历_modPath下的所有文件，进行备份文件的还原和清理操作
                try
                {
                    var di = new DirectoryInfo(_modPath);
                    foreach (var file in di.GetFiles())
                    {
                        // 检查对应的.bak文件是否存在，如果不存在，跳过当前文件
                        string backupPath = $"{file.FullName}.bak";
                        if (!File.Exists(backupPath)) continue;
                        Console.WriteLine($"正在处理文件 {file.FullName}");
                        // 尝试删除当前文件，为备份文件的还原做准备
                        try
                        {
                            file.Delete();
                        }
                        catch (Exception deleteException)
                        {
                            // 打印删除文件时可能出现的异常信息
                            Console.WriteLine($"删除文件 {file.FullName} 时出错: {deleteException.Message}");
                        }

                        // 将.bak文件还原为原始文件
                        try
                        {
                            File.Move(backupPath, backupPath[..^4]);
                        }
                        catch (Exception moveException)
                        {
                            // 打印还原备份文件时可能出现的异常信息
                            Console.WriteLine($"还原备份文件 {backupPath} 时出错: {moveException.Message}");
                        }
                    }
                }
                catch (Exception generalException)
                {
                    // 打印处理目录操作时可能出现的异常信息
                    Console.WriteLine($"处理目录 {_patchPath} 时出现异常: {generalException.Message}");
                }
            }

            // 输出关闭程序的消息，并退出应用程序
            Console.WriteLine("程序正在关闭，已尝试清理由解压操作生成的新文件并还原备份文件。");
        }

        private void CallAuthor_Click(object sender, EventArgs e)
        {
            try
            {
                Process.Start(new ProcessStartInfo
                {
                    FileName = "http://wpa.qq.com/msgrd?v=3&uin=2252905453&site=qq&menu=yes",
                    UseShellExecute = true
                });
            }
            catch (Exception ex)
            {
                MessageBox.Show($"无法打开链接: {ex.Message}");
            }
        }

    }
}